import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:get/get.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/models/common/AccessCodeResetPasswordDto.dart';
import 'package:ichinesereader/models/common/LoginDto.dart';
import 'package:ichinesereader/models/common/Passwords.dart';
import 'package:ichinesereader/models/common/ProfileDTO.dart';
import 'package:ichinesereader/models/individual/subscriptionUserDetails.dart';
import 'package:ichinesereader/models/parent/linkChildDto.dart';
import 'package:ichinesereader/models/parent/miniProfile.dart';
import 'package:ichinesereader/utils/commonApi.dart';
import 'package:ichinesereader/models/common/userStatusDto.dart';
import 'package:ichinesereader/models/school/newStudentDto.dart';
import 'package:ichinesereader/models/school/studentNamesList.dart';
import 'package:ichinesereader/models/school/teacherUpdateDto.dart';
import 'package:ichinesereader/utils/log.dart';
import 'package:ichinesereader/models/school/teacherCreateDto.dart';

class UserServiceProvider extends GetConnect with CommonApi {
  UserServiceProvider() {
    httpClient.addResponseModifier((request, response) {
      if (response.statusCode == 403) {
        Log.debug('${request.url} 403 error');
        if (!Get.isSnackbarOpen) {
          Get.snackbar(
            'Message'.tr,
            'You have been logged out due to inactivity or security reasons.'
                .tr,
            snackPosition: SnackPosition.BOTTOM,
            backgroundColor: Color(0xff23c6c8),
            colorText: Color(0xffd8ffff),
          );
        }
        if (EasyLoading.isShow) {
          EasyLoading.dismiss();
        }
        if (Get.currentRoute != '/login') {
          return Get.offAllNamed('/login');
        }
      } else if (response.statusCode == 401) {
        Log.debug('${request.url} unauthorized access');
        if (!Get.isSnackbarOpen) {
          Get.snackbar('Message'.tr, 'Unauthorized access'.tr,
              backgroundColor: Color(0xff23c6c8),
              colorText: Color(0xffd8ffff),
              snackPosition: SnackPosition.BOTTOM);
        }
        if (EasyLoading.isShow) {
          EasyLoading.dismiss();
        }
        if (Get.currentRoute != '/login') {
          return Get.offAllNamed('/login');
        }
      } else {
        Log.debug(response.request?.url.toString());
        return response;
      }
    });
    httpClient.maxAuthRetries = 2;
    httpClient.timeout = Duration(seconds: 30);
  }

  Future<http.Response> loginAsync(LoginDto login) async {
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/login');

    if (login.accessCode != null && login.accessCode != '') {
      url = Uri.parse('${Constants.BaseAPI}usermanager/loginByQRCode');
    }

    final response = await http.post(
      url,
      headers: <String, String>{
        "content-type": "application/json;charset=UTF-8"
      },
      body: loginDtoToJson(login),
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  Future<http.Response> resetPasswordByEmail(String username) async {
    Uri url = Uri.parse(
        '${Constants.BaseAPI}usermanager/resetpassword/email/$username');
    final response = await http.get(
      url,
      headers: <String, String>{
        "content-type": "application/json;charset=UTF-8"
      },
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  Future<http.Response> resetPasswordBySecurityIdentifier(
      AccessCodeResetDto dto) async {
    Uri url =
        Uri.parse('${Constants.BaseAPI}usermanager/resetpassword/accesscode');
    final response = await http.post(
      url,
      headers: <String, String>{
        "content-type": "application/json;charset=UTF-8"
      },
      body: accessCodeResetDtoToJson(dto),
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  Future<http.Response> unlock(String? authtoken) async {
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/unlocked');
    final response = await http.get(
      url,
      headers: <String, String>{"authtoken": '$authtoken'},
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  Future<http.Response> validateUser(String? authtoken) async {
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/profilenew');
    final response = await http.get(
      url,
      headers: <String, String>{"authtoken": '$authtoken'},
    );
    //Log.debug(response.body);
    return response;
  }

  Future<bool> usernameAvailable(String userName) async {
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/available/$userName');
    final response = await http.get(url);
    Log.debug(response.request?.url.toString());
    Log.debug(response.body);
    if (response.body == 'true') {
      return true;
    } else {
      return false;
    }
  }

  Future<bool> emailAvailable(String email) async {
    Uri url =
        Uri.parse('${Constants.BaseAPI}usermanager/available/email/$email');
    final response = await http.get(url);
    Log.debug(response.request?.url.toString());
    Log.debug(response.body);
    if (response.body == 'true') {
      return true;
    } else {
      return false;
    }
  }

  Future<bool> logoutAsync() async {
    final box = Hive.box('appconfig');
    var authtoken = box.get(CacheManagerKey['authtoken'].toString());
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/logout');
    final response = await http.delete(
      url,
      headers: <String, String>{"authtoken": '$authtoken'},
    );
    Log.debug(response.request?.url.toString());
    if (response.statusCode == 200) {
      return true;
    } else {
      return false;
    }
  }

  Future<dynamic> getProfileService() async {
    final box = Hive.box('appconfig');
    var authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}usermanager/profilenew',
      headers: <String, String>{"authtoken": '$authtoken'},
    );
    return response;
  }

  Future<dynamic> updateProfileService(ProfileDTO profile) async {
    final box = Hive.box('appconfig');
    profile.theme = box.get('theme').toString();
    profile.lang = box.get('locale').toString();

    String url = '${Constants.BaseAPI}usermanager/profilenew';
    String jsonData = profileUpdateToJson(profile);
    return commonApiPost(this, url, jsonData: jsonData, showFullLog: true);
  }

  Future<dynamic> changeUserPassword(Passwords data) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await post(
      '${Constants.BaseAPI}usermanager/changePassword',
      passwordsToJson(data),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      //body: passwordsToJson(data),
    );
    return response;
  }

  Future<dynamic> getUserAvatar() async {
    final box = Hive.box('appconfig');
    var authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}storage/avatar',
      headers: <String, String>{"authtoken": '$authtoken'},
    );
    return response;
  }

  Future<dynamic> getLeaderBoardAll() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    //Uri url = Uri.parse('${Constants.BaseAPI}superadmin/leaderboardEx');
    final response = await get(
      '${Constants.BaseAPI}superadmin/leaderboardEx',
      headers: <String, String>{"authtoken": _authtoken},
    );
    return response;
  }

  Future<dynamic> getLeaderBoardByClass(String classId) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    //Uri url = Uri.parse('${Constants.BaseAPI}superadmin/leaderboard/$classId');
    final response = await get(
      '${Constants.BaseAPI}superadmin/leaderboard/$classId',
      headers: <String, String>{"authtoken": _authtoken},
    );
    return response;
  }

  Future<dynamic> getClasses() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}usermanager/getClasses',
      headers: <String, String>{"authtoken": _authtoken},
    );
    //Log.debug(response.body);
    return response;
  }

  Future<dynamic> getClassSettingsByClassId(String classId) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}schoolmanager/getClassSettings/$classId',
      headers: <String, String>{"authtoken": _authtoken},
    );
    return response;
  }

  Future<dynamic> refreshLevelPercentage() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}usermanager/refreshLevelPercentage',
      headers: <String, String>{
        'authtoken': _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }

  Future<bool> getUnlock() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/unlocked');
    final response = await http.get(
      url,
      headers: <String, String>{"authtoken": _authtoken},
    );
    Log.debug(response.request?.url.toString());
    if (response.statusCode == 200) {
      //Log.debug('RETURNING: ' + response.body);
      return true;
    } else {
      throw Exception('Failed to unlock user');
    }
  }

  Future<Map<String, dynamic>> logIn(userName, password) async {
    Uri url = Uri.parse(Constants.BaseAPI + 'usermanager/login');
    final response = await http.post(url,
        //headers: <String, String>{"Content-Type": "application/json"},
        body: jsonEncode(<String, String>{
          'userName': userName,
          'password': password,
          'sessionType': 'WEB'
        }));
    Map<String, dynamic> body = jsonDecode(response.body);
    Log.debug(body.runtimeType);
    Log.debug(response.request?.url.toString());
    //return jsonDecode(response.body);
    return jsonDecode(
        jsonEncode({'body': response.body, 'statusCode': response.statusCode}));
  }

/////students
////{"status":1000,"message":"Congratulations, your account has been created successfully. ","result":null}
  Future<dynamic> createStudent(StudentDetailsDto data) async {
    String url = '${Constants.BaseAPI}usermanager/createStudent';
    String jsonData = studentDetailsDtoToJson(data);
    return commonApiPost(this, url, jsonData: jsonData, showFullLog: true);
    // final response = await post(
    //   '${Constants.BaseAPI}usermanager/createStudent',
    //   studentDetailsDtoToJson(data),
    //   headers: <String, String>{
    //     "authtoken": _authtoken,
    //     'content-type': 'application/json;charset=UTF-8'
    //   },
    //   //body: studentDetailsDtoToJson(data),
    // );
    //
    // return response;
  }

//////{"status":1000,"message":"Congratulations, student account has  updated successfully. ","result":null}
  Future<dynamic> updateStudent(StudentDetailsDto data) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    // Uri url = Uri.parse(
    //     '${Constants.BaseAPI}usermanager/studentUpdate/${data.userName}');
    final response = await post(
      '${Constants.BaseAPI}usermanager/studentUpdate/${data.userName}',
      studentDetailsDtoToJson(data),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      //body: studentDetailsDtoToJson(data),
    );
    return response;
  }

  //////return null
  Future<dynamic> resetStudentPassword(String userName, String passWord) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await put(
      '${Constants.BaseAPI}usermanager/password/student/reset/$userName',
      {'newPassword': '$passWord'},
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }

/////[{"propertyName":"ttttttsssssss","message":"is successfully disabled"}]
  Future<dynamic> updateStudentStatus(UserStatusDto dto) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    //Uri url = Uri.parse('${Constants.BaseAPI}usermanager/updateUserStatus');
    final response = await post(
      '${Constants.BaseAPI}usermanager/updateUserStatus',
      userStatusDtoToJson(dto),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      //body: userStatusDtoToJson(dto),
    );
    return response;
  }

// ////// return nulll, same as delete students
//   Future<http.Response> removeStudents(StudentNamesList data) async {
//     final box = Hive.box('appconfig');
//     var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
//     Uri url = Uri.parse('${Constants.BaseAPI}usermanager/deleteStudents');
//     final response = await http.delete(
//       url,
//       headers: <String, String>{
//         "authtoken": _authtoken,
//         'content-type': 'application/json;charset=UTF-8'
//       },
//       body: studentNamesListToJson(data),
//     );
//     Log.debug(response.request?.url.toString());
//     return response;
//   }

////// delete students, same as remove students
  Future<http.Response> deleteStudents(StudentNamesList data) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/deleteStudents');
    final response = await http.delete(
      url,
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      body: studentNamesListToJson(data),
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  ///teacher

//{"status":1000,"message":"Congratulations, your account has been created successfully. ","result":null}
  Future<dynamic> createTeacher(TeacherCreateDto data) async {
    String url = '${Constants.BaseAPI}usermanager/createTeacher';
    String jsonData = teacherCreateDtoToJson(data);
    return commonApiPost(this, url, jsonData: jsonData, showFullLog: true);
    // final response = await post(
    //   '${Constants.BaseAPI}usermanager/createTeacher',
    //   teacherCreateDtoToJson(data),
    //   headers: <String, String>{
    //     "authtoken": _authtoken,
    //     'content-type': 'application/json;charset=UTF-8'
    //   },
    //   //body: studentDetailsDtoToJson(data),
    // );
    // return response;
  }

//{"status":1000,"message":"your account has deleted successfully","result":null}
  Future<dynamic> removeTeacher(String userName) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    // Uri url =
    //     Uri.parse('${Constants.BaseAPI}usermanager/deleteTeacher/$userName');
    final response = await delete(
      '${Constants.BaseAPI}usermanager/deleteTeacher/$userName',
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }

  Future<dynamic> updateTeacherStatus(UserStatusDto dto) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    //Uri url = Uri.parse('${Constants.BaseAPI}usermanager/updateTeacherStatus');
    final response = await post(
      '${Constants.BaseAPI}usermanager/updateTeacherStatus',
      userStatusDtoToJson(dto),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      //body: userStatusDtoToJson(dto),
    );
    return response;
  }

  Future<dynamic> updateTeacherDetails(
      String userName, TeacherUpdateDto dto) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    // Uri url =
    //     Uri.parse('${Constants.BaseAPI}usermanager/teacherUpdate/$userName');
    Log.debug("teacherUpdateDtoToJson=${teacherUpdateDtoToJson(dto)}");
    final response = await post(
      '${Constants.BaseAPI}usermanager/teacherUpdate/$userName',
      teacherUpdateDtoToJson(dto),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      //body: teacherUpdateDtoToJson(dto),
    );
    return response;
  }

//return null
  Future<dynamic> updateTeacherEmail(String oldEmail, String newEmail) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    // Uri url = Uri.parse(
    //     '${Constants.BaseAPI}usermanager/email/teacher/reset/$oldEmail/$newEmail');
    final response = await put(
      '${Constants.BaseAPI}usermanager/email/teacher/reset/$oldEmail/$newEmail',
      {},
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
      //body: {},
    );
    return response;
  }

  Future<dynamic> resetTeacherPassword(
      String userName, String newPassword) async {
    String url =
        '${Constants.BaseAPI}usermanager/password/teacher/reset/$userName';
    dynamic jsonData = {'newPassword': '$newPassword'};
    return commonApiPut(this, url, jsonData: jsonData, showFullLog: true);
  }

  Future<dynamic> resetTeacherEmail(String userName, String email) async {
    // usermanager/email/teacher/reset/ning-teacher1/715617887@qq.com
    String url =
        '${Constants.BaseAPI}usermanager/email/teacher/reset/$userName/$email';
    return commonApiPut(this, url, showFullLog: true);
  }

  ///reports
  /// childrenHistoryResult
  Future<dynamic> getChildrenHistory(String userName) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}usermanager/children/history/$userName',
      headers: <String, String>{
        'authtoken': _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }

  Future<http.Response> hasPlacementTest() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    Uri url = Uri.parse(
        '${Constants.BaseAPISuper}superadmin/question/record/count?PRE_TEST');
    final response = await http.get(
      url,
      headers: <String, String>{"authtoken": _authtoken},
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  Future<dynamic> hasNewAssessments() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPISuper}superadmin/assessment/mine/count',
      headers: <String, String>{"authtoken": _authtoken},
    );
    return response;
  }

  Future<dynamic> hasNewAssignments() async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await get(
      '${Constants.BaseAPI}schoolmanager/isunreadAssignmentExist',
      headers: <String, String>{"authtoken": _authtoken},
    );
    return response;
  }

////only for individual
  Future<http.Response> getSubscriptionPlans() async {
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/payment/plans');
    final response = await http.get(
      url,
      headers: <String, String>{
        "content-type": "application/json;charset=UTF-8"
      },
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  Future<http.Response> getSubscriptionToken(
      SubscriptionUserDetails userDetails) async {
    Uri url = Uri.parse('${Constants.BaseAPI}usermanager/payment/get_token');
    final response = await http.post(
      url,
      headers: <String, String>{
        "content-type": "application/json;charset=UTF-8"
      },
      body: subscriptionUserDetailsToJson(userDetails),
    );
    Log.debug(response.request?.url.toString());
    return response;
  }

  //for parent
  Future<dynamic> unlinkChild(String userName) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await put(
      '${Constants.BaseAPI}usermanager/unlinkchild/$userName',
      {},
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }

  Future<dynamic> linkChild(LinkChildDto dto) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await put(
      '${Constants.BaseAPI}usermanager/linkchild',
      linkChildDtoToJson(dto),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }

  //for parent
  Future<dynamic> updateChild(String userName, MiniProfile profile) async {
    final box = Hive.box('appconfig');
    var _authtoken = box.get(CacheManagerKey['authtoken'].toString());
    final response = await post(
      '${Constants.BaseAPI}usermanager/updateProfileByParent/$userName',
      miniProfileToJson(profile),
      headers: <String, String>{
        "authtoken": _authtoken,
        'content-type': 'application/json;charset=UTF-8'
      },
    );
    return response;
  }
}
